#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "cpu.h"

uint32_t ram[0x4000];

sem_t mem_sem, cpu_sem;

static void usage(void)
{
    fprintf(stderr, "usage: armemu ram-image.bin\n");
    exit(2);
}

int main(int argc, char **argv)
{
    FILE *fp;
    pthread_t cpu_thread;

    if (argc != 2) {
        usage();
    }

    fp = fopen(argv[1], "rb");
    if (!fp) {
        perror(argv[1]);
        return 1;
    }

    // 读取RAM内容
    fread(ram, 1, 0x10000, fp);
    fclose(fp);

    cpu_init();

    sem_init(&mem_sem, 0, 0);
    sem_init(&cpu_sem, 0, 0);
    pthread_create(&cpu_thread, NULL, cpu_proc, NULL);

    for (;;) {
        sem_post(&cpu_sem);
        sem_wait(&mem_sem);
        if (bus_out[0]&2) {
            break;
        }
        // time to provide input
        if (bus_out[0]&1) {
            bus_in[1] = ram[(bus_out[1] & 0xffff) >> 2];
            bus_in[0] = 1;
        } else if (bus_out[0]&4) {
            bus_in[2] = ram[(bus_out[2] & 0xffff) >> 2];
            bus_in[0] = 2;
        } else if (bus_out[0]&8) {
            uint32_t mask = 0;
            if (bus_out[0]>>4&1) mask |= 0x000000ff;
            if (bus_out[0]>>5&1) mask |= 0x0000ff00;
            if (bus_out[0]>>6&1) mask |= 0x00ff0000;
            if (bus_out[0]>>7&1) mask |= 0xff000000;
            uint32_t q = ram[(bus_out[2] & 0xffff) >> 2];
            uint32_t d = bus_out[3] & mask | q & ~mask;
            ram[(bus_out[2] & 0xffff) >> 2] = d;
            bus_in[0] = 2;
        }
    }

    return 0;
}

// vim: sw=4 expandtab
